package main

import (
	"fmt"
	"log"
)

//全局变量
var num int = 10

func main() {

	//getName("carrymec")
	//fmt.Println(getSumAndMax(5, 1))
	//fmt.Println(int3(1, 2, 3))

	//Go语言中的defer语句会将其后面跟随的语句进行延迟处理。
	// 在defer归属的函数即将返回时，将延迟处理的语句按defer定义的逆序进行执行，
	// 也就是说，先被defer的语句最后被执行，最后被defer的语句，
	// 最先被执行。
	//defer延迟函数
	//fmt.Println("start ...")
	//defer fmt.Println(1)
	//defer fmt.Println(2)
	//defer testGlobal()
	//fmt.Println("end...")
	//testGlobal()

	//abc := testGlobal
	//fmt.Printf("%T", abc)
	//fmt.Println(calc(1, 2, add))
	//fmt.Println(calc1(1, 2, do("-")))

	//var f = adder(10)
	//fmt.Println(f(10)) //10
	//fmt.Println(f(20)) //30
	//fmt.Println(f(30)) //60
	//
	//f1 := adder(10)
	//fmt.Println(f1(40)) //40
	//fmt.Println(f1(50)) //90

	//fmt.Println("f1",f1())
	//fmt.Println("f3",f3())
	//fmt.Println("f4",f4())
	//fmt.Println("f2",f2())

	x := 1
	y := 2
	defer calc11("AA", x, calc11("A", x, y))
	x = 10
	defer calc11("BB", x, calc11("B", x, y))
	y = 20

}
func f1() int {
	x := 5
	log.Println("outside", x)
	defer func() {
		x++
		log.Println("defer", x)
	}()
	return x
}
func f2() (x int) {
	log.Println("f2", x)
	defer func() {
		log.Println("f2 defer ++before", x)
		x++
		log.Println("f2 defer", x)
	}()
	return 5
}
func f3() (y int) {
	x := 5
	defer func() {
		x++
	}()
	return x
}
func f4() (x int) {
	defer func(x int) {
		x++
	}(x)
	return 5
}
func calc11(index string, a, b int) int {
	ret := a + b
	fmt.Println(index, a, b, ret)
	//fmt.Println(ret)
	return ret
}

func getName(name string) string {

	fmt.Println(name)
	return name
}

//返回多个值
func getSumAndMax(x int, y int) (int, int) {
	tem := 0
	if x-y > 0 {
		tem = x
	} else {
		tem = y
	}
	return x + y, tem
}

//可变参数,在某个参数后面加 ...是可变参数，在函数体中是切片类型
func int3(a ...int) int {

	ret := 0
	for _, arg := range a {
		ret = ret + arg
	}

	fmt.Printf("%T\n", a)
	return ret
}

//固定参数 加上可变参数，可变参数必须放在固定参数后面
//go语言中的函数没有默认参数，支持多返回值
func int2(a int, b ...int) int {

	return 0
}

func testGlobal() {
	//如果在局部能找到值就返回自己的值 找不到就去找全局变量
	num := 100
	fmt.Println(num)
}

func add(a int, b int) int {
	return a + b
}

func sub(a int, b int) int {
	return a - b
}

//函数当参数使用
func calc(x, y int, op func(int, int) int) int {
	return op(x, y)
}

func calc1(x, y int, op func(int, int) int) int {
	return op(x, y)
}

//函数当返回值
func do(s string) func(int, int) int {
	switch s {
	case "+":
		return add
	case "-":
		return sub
	default:
		//err := errors.New("无法识别的操作符")
		return nil
	}
}

func adder(x int) func(int) int {

	return func(y int) int {
		x += y
		return x
	}
}
